//==============================================================================
//
//               Copyright (C) 2003  Dick van Oudheusden
//  
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//==============================================================================
// 
//  $Date: 2008-01-05 06:06:33 $ $Revision: 1.2 $
//
//==============================================================================

#include <stdlib.h>
#include <math.h>

#include "ofc/config.h"

#include "ofc/DMRnd.h"
#include "ofc/DRndDist.h"

#include "DInc.h"
#include "DTest.h"

//-Misc------------------------------------------------------------------------

void DRndDist_test()
{
  DMRnd    *rnd       = [DMRnd alloc];

  STARTTEST();

  [rnd init :5489];

  TEST(fabs([DRndDist nextNormal :rnd :0.0 :0.5] - (-0.44759539)) < 0.00000001);
  TEST(fabs([DRndDist nextNormal :rnd :0.0 :0.5] - ( 0.04488381)) < 0.00000001);
  TEST(fabs([DRndDist nextNormal :rnd :0.0 :0.5] - (-0.37048549)) < 0.00000001);
  TEST(fabs([DRndDist nextNormal :rnd :0.0 :0.5] - ( 0.22997112)) < 0.00000001);
  TEST(fabs([DRndDist nextNormal :rnd :0.0 :0.5] - ( 0.49689682)) < 0.00000001);
  TEST(fabs([DRndDist nextNormal :rnd :0.0 :0.5] - (-0.87176322)) < 0.00000001);
  TEST(fabs([DRndDist nextNormal :rnd :0.0 :0.5] - (-0.57489741)) < 0.00000001);
  TEST(fabs([DRndDist nextNormal :rnd :0.0 :0.5] - ( 1.42277046)) < 0.00000001);
  TEST(fabs([DRndDist nextNormal :rnd :0.0 :0.5] - ( 0.07756191)) < 0.00000001);
  TEST(fabs([DRndDist nextNormal :rnd :0.0 :0.5] - ( 0.74235660)) < 0.00000001);

  TEST(fabs([DRndDist nextExponential :rnd :0.5] - (1.66613875)) < 0.00000001);
  TEST(fabs([DRndDist nextExponential :rnd :0.5] - (0.50903162)) < 0.00000001);
  TEST(fabs([DRndDist nextExponential :rnd :0.5] - (0.08177190)) < 0.00000001);
  TEST(fabs([DRndDist nextExponential :rnd :0.5] - (0.77576300)) < 0.00000001);
  TEST(fabs([DRndDist nextExponential :rnd :0.5] - (0.03414304)) < 0.00000001);
  TEST(fabs([DRndDist nextExponential :rnd :0.5] - (0.19183258)) < 0.00000001);
  TEST(fabs([DRndDist nextExponential :rnd :0.5] - (0.19376214)) < 0.00000001);
  TEST(fabs([DRndDist nextExponential :rnd :0.5] - (0.45972471)) < 0.00000001);
  TEST(fabs([DRndDist nextExponential :rnd :0.5] - (0.13870740)) < 0.00000001);
  TEST(fabs([DRndDist nextExponential :rnd :0.5] - (0.15011541)) < 0.00000001);

  TEST(fabs([DRndDist nextGamma :rnd :15.0 :0.5] - (7.01523132)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :15.0 :0.5] - (8.25312323)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :15.0 :0.5] - (6.57587412)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :15.0 :0.5] - (6.31248523)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :15.0 :0.5] - (3.99324402)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :15.0 :0.5] - (4.72211717)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :15.0 :0.5] - (5.35435538)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :15.0 :0.5] - (8.49411653)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :15.0 :0.5] - (6.97074297)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :15.0 :0.5] - (7.00845102)) < 0.00000001);

  TEST(fabs([DRndDist nextGamma :rnd :0.5 :0.5] - (1.47727187)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :0.5 :0.5] - (1.33811752)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :0.5 :0.5] - (0.56072758)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :0.5 :0.5] - (0.32241659)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :0.5 :0.5] - (3.42835869)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :0.5 :0.5] - (0.00049857)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :0.5 :0.5] - (1.87629944)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :0.5 :0.5] - (0.31658686)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :0.5 :0.5] - (0.04855770)) < 0.00000001);
  TEST(fabs([DRndDist nextGamma :rnd :0.5 :0.5] - (0.07316919)) < 0.00000001);

  TEST(fabs([DRndDist nextBeta :rnd :0.1 :  0.1] - (0.99993960)) < 0.00000001);
  TEST(fabs([DRndDist nextBeta :rnd :0.2 :  1.1] - (0.32639035)) < 0.00000001);
  TEST(fabs([DRndDist nextBeta :rnd :0.3 :  3.1] - (0.00575353)) < 0.00000001);
  TEST(fabs([DRndDist nextBeta :rnd :0.4 :  7.1] - (0.10315773)) < 0.00000001);
  TEST(fabs([DRndDist nextBeta :rnd :0.5 : 15.9] - (0.01867630)) < 0.00000001);
  TEST(fabs([DRndDist nextBeta :rnd :0.6 : 31.9] - (0.00562753)) < 0.00000001);
  TEST(fabs([DRndDist nextBeta :rnd :0.7 : 63.9] - (0.00268437)) < 0.00000001);
  TEST(fabs([DRndDist nextBeta :rnd :0.8 :127.9] - (0.00573342)) < 0.00000001);
  TEST(fabs([DRndDist nextBeta :rnd :0.9 :255.9] - (0.00201518)) < 0.00000001);
  TEST(fabs([DRndDist nextBeta :rnd :1.0 :511.9] - (0.00109881)) < 0.00000001);

  TEST([DRndDist nextBinomial :rnd :0.9 : 5] == 4 );
  TEST([DRndDist nextBinomial :rnd :0.8 :15] == 11);
  TEST([DRndDist nextBinomial :rnd :0.7 :25] == 21);
  TEST([DRndDist nextBinomial :rnd :0.6 :35] == 21);
  TEST([DRndDist nextBinomial :rnd :0.5 :45] == 20);
  TEST([DRndDist nextBinomial :rnd :0.4 :55] == 24);
  TEST([DRndDist nextBinomial :rnd :0.3 :65] == 16);
  TEST([DRndDist nextBinomial :rnd :0.2 :75] == 13);
  TEST([DRndDist nextBinomial :rnd :0.1 :85] == 15);
  TEST([DRndDist nextBinomial :rnd :0.0 :95] == 0 );

  TEST([DRndDist nextPoisson :rnd :0.5 ] == 0 );
  TEST([DRndDist nextPoisson :rnd :2.5 ] == 5 );
  TEST([DRndDist nextPoisson :rnd :4.5 ] == 3 );
  TEST([DRndDist nextPoisson :rnd :6.5 ] == 5 );
  TEST([DRndDist nextPoisson :rnd :8.5 ] == 8 );
  TEST([DRndDist nextPoisson :rnd :10.5] == 13);
  TEST([DRndDist nextPoisson :rnd :12.5] == 10);
  TEST([DRndDist nextPoisson :rnd :14.5] == 10);
  TEST([DRndDist nextPoisson :rnd :16.5] == 16);
  TEST([DRndDist nextPoisson :rnd :18.5] == 17);

  TEST(fabs([DRndDist nextPareto :rnd :0.5 :0.5] - (3.19627113)) < 0.00000001);
  TEST(fabs([DRndDist nextPareto :rnd :0.5 :1.5] - (0.67574893)) < 0.00000001);
  TEST(fabs([DRndDist nextPareto :rnd :1.5 :2.5] - (2.23881531)) < 0.00000001);
  TEST(fabs([DRndDist nextPareto :rnd :0.5 :3.5] - (0.85719001)) < 0.00000001);
  TEST(fabs([DRndDist nextPareto :rnd :2.5 :4.5] - (2.50672614)) < 0.00000001);
  TEST(fabs([DRndDist nextPareto :rnd :0.5 :5.5] - (0.52442780)) < 0.00000001);
  TEST(fabs([DRndDist nextPareto :rnd :3.5 :6.5] - (5.79460199)) < 0.00000001);
  TEST(fabs([DRndDist nextPareto :rnd :0.5 :7.5] - (0.50829023)) < 0.00000001);
  TEST(fabs([DRndDist nextPareto :rnd :0.5 :8.5] - (0.50722690)) < 0.00000001);
  TEST(fabs([DRndDist nextPareto :rnd :4.5 :9.5] - (4.51976424)) < 0.00000001);

  TEST(fabs([DRndDist nextWeibull :rnd :0.5 :0.5] - (0.00411372)) < 0.00000001);
  TEST(fabs([DRndDist nextWeibull :rnd :0.5 :1.5] - (1.26279804)) < 0.00000001);
  TEST(fabs([DRndDist nextWeibull :rnd :1.5 :2.5] - (0.83024858)) < 0.00000001);
  TEST(fabs([DRndDist nextWeibull :rnd :0.5 :3.5] - (0.41924933)) < 0.00000001);
  TEST(fabs([DRndDist nextWeibull :rnd :2.5 :4.5] - (3.01282633)) < 0.00000001);
  TEST(fabs([DRndDist nextWeibull :rnd :0.5 :5.5] - (0.39286396)) < 0.00000001);
  TEST(fabs([DRndDist nextWeibull :rnd :3.5 :6.5] - (3.66115208)) < 0.00000001);
  TEST(fabs([DRndDist nextWeibull :rnd :0.5 :7.5] - (0.50733162)) < 0.00000001);
  TEST(fabs([DRndDist nextWeibull :rnd :0.5 :8.5] - (0.50523448)) < 0.00000001);
  TEST(fabs([DRndDist nextWeibull :rnd :4.5 :9.5] - (4.85256504)) < 0.00000001);

  [rnd free];
  
  STOPTEST();
}

